#include <stdio.h>
#include <malloc.h>
struct node
{
int value;
struct node *next;
};
struct node *first= NULL;
struct node *first2=NULL;
// program to append in the linking list
void append(struct node *list, int x)
{
struct node *new_node;
new_node=malloc(sizeof(struct node));
if(list==NULL)
{
new_node->value=x;
new_node->next=NULL;
first=new_node;
}
else
{
while(1)
{
if(list->next==NULL)
{
new_node->value=x;
new_node->next=NULL;
list->next=new_node;
break;
}
list=list->next;
}
}
}

// program to insert at a given position in the list
void insert(struct node *list, int in,int x)
{
int count=0;
struct node *new_node;
new_node=malloc(sizeof(struct node));
if(in==0)
{
new_node->value=x;
new_node->next=list;
first=new_node;
}
else
{
while(list!=NULL)
{	if(count==in-1)
		break;
	list=list->next;
	count++;
	
}
if(list==NULL)
printf("position at which u want to insert is out of range \n");
else
{
new_node->value=x;
new_node->next=list->next;
list->next=new_node;
}
}
}
//program to delete element from the list
void delete(struct node *list, int n)
{
  struct node *cur,  *prev;
	  
  for ( cur=list,prev = NULL;
       cur != NULL && cur->value != n;
       prev = cur, cur = cur->next)
    ;
  if(cur==NULL)
     printf("n value is not in the linked list \n");
   else            
 {
 if (prev == NULL)
    list = list->next; 
      
  else
    prev->next = cur->next;   
  free(cur);
}
  
}

// program to pop element from the list at a given position
void pop1(struct node *list, int n)
{
  int count;
  struct node *cur,  *prev;
	  
  for ( cur=list,prev = NULL,count=0;
       cur != NULL && count != n;
       prev = cur, cur = cur->next,count++)
    ;
  if(cur==NULL)
     printf("index out of range \n");
   else            
 {
 if (prev == NULL)
    list = list->next; 
      
  else
    prev->next = cur->next;   
  free(cur);
}
  
}

// program to return index of a given value
int index( struct node *list, int x)
{
int count=0;
for(;list!=NULL && list->value!=x;list=list->next,count++);
if (list==NULL)
	printf(" element is not in the list \n");
else
return count;
}

// program to find the count of element
int count(struct node *list,int x)
{
int count=0;
if(list==NULL)
return count;
else
{
while(list!=NULL)
{
if(list->value==x)
count++;
list=list->next;
}
return count;
}
}

// program to extend the list
void extend(struct node *list,struct node *list1)
{
while(list->next!=NULL)
{
list=list->next;
} 
list->next=list1;
}

//program to find maximum element of the list
int max(struct node *list)
{
int max;
max=list->value;
while(list!=NULL)
{
if(max < list->value)
 max=list->value;
list=list->next;
}
return max;
}


//program to find minimum element of the list
int min(struct node *list)
{
int min;
min=list->value;
while(list!=NULL)
{
if(min > list->value)
 min=list->value;
list=list->next;
}
return min;
}

// program to reverse the list
struct node *reverse(struct node *list)
{
struct node *cur, *prev, *p;
cur=list;
prev=NULL;
while(cur!=NULL)
{
p=malloc(sizeof(struct node));
p->value=cur->value;
p->next=prev;
prev=p;
cur=cur->next;
}
return p;
}


// program to display elements of the linking list
struct node *display(struct node *list)
{
printf("the linked list is as follows \n");
while(list!=NULL)
{
printf("%d\n",list->value);
list=list->next;
}
}

//program to sort the elements of array
void sort(struct node *list)
{
struct node *cur, *prev;
int temp;
prev=first;
while(prev!=NULL)
{
for(cur=prev->next;cur!=NULL;cur=cur->next)
{
if(cur->value > prev->value)
{
temp=prev->value;
prev->value=cur->value;
cur->value=temp;
}
}
prev=prev->next;
}
}
//main
int main()
{
struct node *result;
int x,n,l,in;
printf("enter the value  u want to store in the linked list(enter 0 to terminate) \n");
scanf("%d",&n);

while(1)
{
	if(n==0)
	break;
	struct node *new_node1;
	new_node1=malloc(sizeof(struct node));
	new_node1->value=n;
	new_node1->next=first;
	first=new_node1;
	printf("enter the value  u want to store in the linked list(enter 0 to terminate) \n");
	scanf("%d",&n);
}	
display(first);
printf("enter 0 to append, 1 to delete,2 to pop,3 to insert,4 to return index of element ,5 to return count of element,6 to return the extended list,7 to return the maximum element,8 to return minimum element,9 to reverse the list,10 to sort the list\n");
scanf("%d",&l);
switch(l)
{
case 0:
printf("enter the value u want to append \n");
scanf("%d",&x);
append(first,x);
display(first);
break;

case 1:
printf("enter the value u want to delete \n");
scanf("%d",&x);
delete(first,x);
display(first);
break;

case 2:
printf("enter the position at which u want to pop \n");
scanf("%d",&x);
pop1(first,x);
display(first);
break;

case 3:
printf("enter the position at which u want to insert \n");
scanf("%d",&in);
printf("enter the value u want to insert \n");
scanf("%d",&x);
insert(first,in,x);
display(first);
break;

case 4:
printf(" enter the value u want index of\n");
scanf("%d",&x);
printf("%d",index(first,x));
break;

case 5:
printf("enter the value of which u want the count \n");
scanf("%d",&x);
printf("the count of value is %d",count(first,x));
break;

case 6:
printf("enter the elements of another linked list \n");
printf("enter the value  u want to store in the linked list(enter 0 to terminate) \n");
scanf("%d",&n);
while(1)
{
	if(n==0)
	break;
	struct node *new_node2;
	new_node2=malloc(sizeof(struct node));
	new_node2->value=n;
	new_node2->next=first2;
	first2=new_node2;
	printf("enter the value  u want to store in the linked list(enter 0 to terminate) \n");
	scanf("%d",&n);

}
extend(first,first2);
display(first);
break;

case 7:
printf("the maximum element is %d \n",max(first));
break; 

case 8:
printf("the minimum element is %d \n", min(first));
break;

case 9:
result=reverse(first);
display(result);
break;

case 10:
sort(first);
display(first);
break;

}
}
